module decoder(
    input            clk,
    input            rst_n,
    input            sin,
    input            valid,
    output reg [7:0] sout
);

    reg  [11:0] sreg;
    reg  [11:0] flag;
    wire [7 :0] dreg;
    wire [3 :0] creg;

    always @(posedge clk, negedge rst_n)
    begin
        if (!rst_n) begin
            sreg <= 12'b0;
            flag <= 12'h800;
        end
        else if (valid) begin
            sreg <= {sreg[10:0], sin};
            flag <= {flag[10:0], flag[11]};
        end
    end

    always @(posedge clk, negedge rst_n) begin
        if (!rst_n) begin
            sout <= 8'b0;
        end
        else if (flag[11]) begin
            case (creg)
                4'b0011 : sout <= {~dreg[7], dreg[6:0]};
                4'b0101 : sout <= {dreg[7], ~dreg[6], dreg[5:0]};
                4'b0110 : sout <= {dreg[7:6], ~dreg[5], dreg[4:0]};
                4'b0111 : sout <= {dreg[7:5], ~dreg[4], dreg[3:0]};
                4'b1001 : sout <= {dreg[7:4], ~dreg[3], dreg[2:0]};
                4'b1010 : sout <= {dreg[7:3], ~dreg[2], dreg[1:0]};
                4'b1011 : sout <= {dreg[7:2], ~dreg[1], dreg[0]};
                4'b1100 : sout <= {dreg[7:1], ~dreg[0]};
                default : sout <= dreg;
            endcase
        end
    end

    assign dreg = {sreg[9], sreg[7:5], sreg[3:0]};
    assign creg[0] = sreg[11] ^ sreg[9] ^ sreg[7] ^ sreg[5] ^ sreg[3] ^ sreg[1];
    assign creg[1] = sreg[10] ^ sreg[9] ^ sreg[6] ^ sreg[5] ^ sreg[2] ^ sreg[1];
    assign creg[2] = sreg[8] ^ sreg[7] ^ sreg[6] ^ sreg[5] ^ sreg[0];
    assign creg[3] = sreg[4] ^ sreg[3] ^ sreg[2] ^ sreg[1] ^ sreg[0];

endmodule 